﻿using System;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Xsl;
using log4net;

namespace OrbitOne.Elmah.MailNotifier
{
    public class XsltUtil
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof (XsltUtil));

        /// <summary>   
        /// Transforms the supplied xml using the supplied xslt and returns the    
        /// result of the transformation   
        /// </summary>   
        /// <param name="xml">The xml to be transformed</param>   
        /// <param name="xslt">The xslt to transform the xml</param>   
        /// <returns>The transformed xml</returns>
        public static string TransformXml(string xml, string xslt)
        {
            // Simple data checks   
            if (string.IsNullOrEmpty(xml)) throw new ArgumentNullException("xml");
            if (string.IsNullOrEmpty(xslt)) throw new ArgumentNullException("xslt");

            // Create required readers for working with xml and xslt   
            var xsltInput = new StringReader(xslt);
            var xmlInput = new StringReader(xml);
            var xsltReader = new XmlTextReader(xsltInput);
            var xmlReader = new XmlTextReader(xmlInput);

            // Create required writer for output   
            var sb = new StringBuilder();

            // Create a XslCompiledTransform to perform transformation   
            var xsltTransform = new XslCompiledTransform();

            try
            {
                xsltTransform.Load(xsltReader, new XsltSettings(true, true), null);
                var transformedXml = XmlWriter.Create(sb, xsltTransform.OutputSettings);
                xsltTransform.Transform(xmlReader, transformedXml);
            }
            catch (XmlException xmlEx)
            {
                Log.Error("Could not load XSL transform: \n\n" + xmlEx.Message);
                throw;
            }
            catch (XsltException xsltEx)
            {
                Log.Error("Could not process the XSL: \n\n" + xsltEx.Message + "\nOn line " + xsltEx.LineNumber + " @ " + xsltEx.LinePosition);
                throw;
            }
            catch (Exception ex)
            {
                Log.Error("Could not transform XSL.", ex);

                throw;
            }

            return sb.ToString();
        }
    }
}
